﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package Classes.sim {
    import flash.events.*;
    import Engine.Managers.*;
    import flash.geom.*;
    import Engine.Helpers.*;
    import Events.*;
    import Display.DialogUI.*;
    import Classes.*;
    import Classes.util.*;
    import __AS3__.vec.*;
    import Modules.workers.*;
    import com.greensock.*;
    import Display.*;
    import Classes.orders.*;
    import Classes.doobers.*;
    import Classes.actions.*;
    import Classes.inventory.*;
    import Display.TrainUI.*;
    import Engine.*;
    import Modules.trains.*;
    import Transactions.train.*;
    import Modules.workers.transactions.*;

    public class TrainManager extends EventDispatcher implements IGameWorldUpdateObserver {

        public static const TRAIN_FADE_TIME:Number = 1;
        public static const TRAIN_ARRIVAL_TIME:Number = 4;
        public static const TRAIN_VELOCITY_DELTA:Number = 2;
        public static const SCROLL_TO_TRAIN_STATION_DURATION:Number = 1;
        public static const TRAIN_SOUND_LEAVES:String = "train_leaves";
        public static const TRAIN_SOUND_MOVING:String = "train_moving";
        public static const TRAIN_SOUND_ARRIVES:String = "train_arrives";
        public static const WORKER_SYNC_INTERVAL:int = 30;
        public static const WORKER_SYNC_BEFORE_ARRIVAL:int = 30;
        public static const TRAIN_STATE_IDLE_AWAY:int = 0;
        public static const TRAIN_STATE_EN_ROUTE:int = 1;
        public static const TRAIN_STATE_IDLE_AT_STATION:int = 2;
        public static const TRAIN_STATE_DEPARTING:int = 3;
        public static const TRAIN_STATE_ARRIVING:int = 4;
        public static const TRAIN_STATE_AWAITING_CLEARANCE:int = 5;

        private var m_world:GameWorld;
        private var m_trainStation:TrainStation;
        private var m_trainTracks:TrainTracks;
        private var m_crossings:Array;
        private var m_train:Train;
        private var m_minTileX:Number = 0;
        private var m_minTileY:Number = 0;
        private var m_maxTileX:Number = 0;
        private var m_maxTileY:Number = 0;
        private var m_tripQueue:Vector.<TrainTrip>;
        private var m_currentTrip:TrainTrip;
        private var m_trainTerminalVelocity:Number = 1;
        private var m_trainArrivalTime:int = 0;
        private var m_trainRewardAmount:int = 0;
        private var m_trainSpeed:Number = 0;
        private var m_trainHasClearance:Boolean = false;
        private var m_trainDecelerationDistanceFromStation:Number = 0;
        private var m_hasTrainBegunStop:Boolean = false;
        private var m_trainState:int = 0;
        private var m_trainStartPos:Vector3;
        private var m_trainEndPos:Vector3;
        private var m_trainStationDialog:TrainStationDialog;
        private var m_purchaseCandidateItem:Item;
        private var m_trainStopCells:Vector.<TrainStopCell>;
        private var m_lastTrainStopCellRolledOver:TrainStopCell;
        private var m_trainStopCellTooltip:TrainStopTooltip;
        private var m_lastWorkerSyncTime:Number;
        private var m_hasPerformedAnticipatedArrivalSync:Boolean = false;

        public function TrainManager(_arg1:GameWorld){
            this.m_crossings = [];
            this.m_trainStopCells = new Vector.<TrainStopCell>();
            super();
            this.m_world = _arg1;
            this.m_world.addObserver(this);
            this.m_tripQueue = new Vector.<TrainTrip>();
        }
        public static function getWorkerBucket():String{
            return ((HarvestableResource.WORKER_BUCKET_PREFIX + "0"));
        }

        public function get trainState():int{
            return (this.m_trainState);
        }
        public function get isNeighborGated():Boolean{
            return ((Global.player.neighbors.length < Global.gameSettings.getInt("trainRequiredNeighbors", 0)));
        }
        public function get isBuyAllowed():Boolean{
            return (((((!(Global.isVisiting())) && ((Global.player.level >= Global.gameSettings.getInt("trainBuyMinLevel", 0))))) && (!(this.isNeighborGated))));
        }
        public function get isSellAllowed():Boolean{
            return (((((!(Global.isVisiting())) && ((Global.player.level >= Global.gameSettings.getInt("trainSellMinLevel", 0))))) && (!(this.isNeighborGated))));
        }
        public function get isOrderAllowed():Boolean{
            return (((((this.isBuyAllowed) && (this.isSellAllowed))) && (!(this.isWaitingForTrain))));
        }
        public function get trainArrivalTime():int{
            return (this.m_trainArrivalTime);
        }
        public function get trainRewardAmount():int{
            return (this.m_trainRewardAmount);
        }
        public function get isWaitingForTrain():Boolean{
            return (!((this.m_currentTrip == null)));
        }
        public function get isTrainAwaitingClearance():Boolean{
            return ((this.m_trainState == TRAIN_STATE_AWAITING_CLEARANCE));
        }
        public function get purchaseCandidateItem():Item{
            return (this.m_purchaseCandidateItem);
        }
        public function get currentTrip():TrainTrip{
            return (this.m_currentTrip);
        }
        public function get canBuyNewStations():Boolean{
            return (((((this.isWaitingForTrain) && (!(this.m_currentTrip.isWelcomeTrip)))) && ((this.m_currentTrip.item.workers.amount > this.m_currentTrip.stopIds.length))));
        }
        public function get canSpeedUp():Boolean{
            return (((((this.isWaitingForTrain) && (!(this.m_currentTrip.isWelcomeTrip)))) && ((((this.m_trainState == TRAIN_STATE_EN_ROUTE)) || ((this.m_trainState == TRAIN_STATE_DEPARTING))))));
        }
        public function get trainStopData():Array{
            var _local2:String;
            var _local3:int;
            var _local4:int;
            var _local5:Vector.<String>;
            var _local6:int;
            var _local7:int;
            var _local8:int;
            var _local9:Object;
            var _local1:Array = [];
            if (((this.m_currentTrip) && (!(this.m_currentTrip.isWelcomeTrip)))){
                _local2 = this.m_currentTrip.item.trainPayout;
                _local3 = 0;
                _local4 = (this.m_currentTrip.maxStops + 1);
                _local5 = this.m_currentTrip.stopIds;
                _local6 = 0;
                while (_local6 < _local4) {
                    _local7 = Global.gameSettings.getTieredInt(_local2, _local6);
                    _local8 = (_local7 - _local3);
                    _local3 = _local7;
                    _local9 = {};
                    _local9["commodityType"] = ((this.m_currentTrip.transactionType == TrainWorkers.OP_BUY)) ? "goods" : "coins";
                    _local9["commodityIncrement"] = ((_local8 >= 0)) ? ("+" + _local8) : ("" + _local8);
                    if (_local6 == 0){
                        _local9["uid"] = "-1";
                    } else {
                        if (_local5.length > (_local6 - 1)){
                            if (parseFloat(_local5[(_local6 - 1)]) < 0){
                                _local9["uid"] = "-1";
                            } else {
                                _local9["uid"] = _local5[(_local6 - 1)];
                            };
                        };
                    };
                    _local1.push(_local9);
                    _local6++;
                };
            };
            return (_local1);
        }
        public function get candidateTrainStopData():Array{
            var _local2:String;
            var _local3:int;
            var _local4:int;
            var _local5:int;
            var _local6:int;
            var _local7:int;
            var _local8:Object;
            var _local1:Array = [];
            if (this.m_purchaseCandidateItem){
                _local2 = this.m_purchaseCandidateItem.trainPayout;
                _local3 = 0;
                _local4 = (this.m_purchaseCandidateItem.workers.amount + 1);
                _local5 = 0;
                while (_local5 < _local4) {
                    _local6 = Global.gameSettings.getTieredInt(_local2, _local5);
                    _local7 = (_local6 - _local3);
                    _local3 = _local6;
                    _local8 = {};
                    _local8["commodityType"] = ((this.m_purchaseCandidateItem.goods > 0)) ? "coins" : "goods";
                    _local8["commodityIncrement"] = ((_local7 >= 0)) ? ("+" + _local7) : ("" + _local7);
                    if (_local5 == 0){
                        _local8["uid"] = "-1";
                    };
                    _local1.push(_local8);
                    _local5++;
                };
            };
            return (_local1);
        }
        public function get trainStation():TrainStation{
            return (this.m_trainStation);
        }
        private function createTrain():void{
            if (!this.m_train){
                this.m_train = new Train("train", false);
                this.m_train.setOuter(this.m_world);
                this.m_train.attach();
                this.m_train.setDirection(Constants.DIRECTION_SW);
                this.m_train.setPosition(999, 999);
                this.m_train.displayObject.alpha = 0;
                this.m_train.getStateMachine().addActions(new NPCAction(this.m_train));
                this.m_trainTerminalVelocity = this.m_train.getItem().navigateXml.child("runSpeed");
            };
        }
        private function syncWorkers():void{
            var _local1:TrainWorkers;
            var _local2:TrainTrip;
            if (((Global.trainWorkerManager) && (((!(this.m_currentTrip)) || (((this.m_currentTrip) && (!(this.m_currentTrip.isWelcomeTrip)))))))){
                _local1 = (Global.trainWorkerManager.getWorkers(getWorkerBucket()) as TrainWorkers);
                if (_local1){
                    _local2 = new TrainTrip();
                    _local2.loadFromWorker(_local1);
                    this.m_currentTrip = _local2;
                };
            };
        }
        public function registerTrainStopCell(_arg1:TrainStopCell):void{
            this.m_trainStopCells.push(_arg1);
        }
        public function grantTrainClearance():void{
            if (this.m_trainState == TRAIN_STATE_AWAITING_CLEARANCE){
                this.m_trainHasClearance = true;
                TrainUI.showTrainAtStationHUDIcon(false, this);
            };
        }
        public function speedUpCurrentTrain():void{
            var _local1:TrainWorkers;
            if (this.canSpeedUp){
                if (Global.player.canBuyCash(this.m_currentTrip.item.trainSpeedUpCost, true)){
                    TransactionManager.addTransaction(new TSpeedUpTrain());
                    Global.player.cash = (Global.player.cash - this.m_currentTrip.item.trainSpeedUpCost);
                    _local1 = (Global.trainWorkerManager.addAndGetWorkers(getWorkerBucket()) as TrainWorkers);
                    _local1.timeSent = (_local1.timeSent - this.m_currentTrip.timeLeft);
                    this.m_currentTrip.loadFromWorker(_local1);
                };
            };
        }
        public function purchaseNewStation():void{
            var _local1:TrainWorkers;
            if (((this.canBuyNewStations) && ((this.currentTrip.item.workers.amount > this.currentTrip.stopIds.length)))){
                if (Global.player.canBuyCash(this.m_currentTrip.item.workers.cashCost, true)){
                    GameTransactionManager.addTransaction(new TWorkerPurchase(WorkerManager.FEATURE_TRAINS, getWorkerBucket()));
                    Global.player.cash = (Global.player.cash - this.m_currentTrip.item.workers.cashCost);
                    _local1 = (Global.trainWorkerManager.addAndGetWorkers(getWorkerBucket()) as TrainWorkers);
                    _local1.addWorker(String(-((_local1.numPurchasedWorkers + 1))));
                    _local1.numPurchasedWorkers++;
                    this.m_currentTrip.loadFromWorker(_local1);
                    dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATION_LIST_UPDATE));
                };
            };
        }
        public function scrollToTrainStation():void{
            this.m_world.centerOnObject(this.m_trainStation, SCROLL_TO_TRAIN_STATION_DURATION);
        }
        public function showTrainStationDialog():void{
            if ((((this.m_trainState == TRAIN_STATE_ARRIVING)) || ((this.m_trainState == TRAIN_STATE_IDLE_AT_STATION)))){
                return;
            };
            this.m_trainStopCells = new Vector.<TrainStopCell>();
            this.m_trainStationDialog = new TrainStationDialog();
            this.m_trainStationDialog.addEventListener(Event.CLOSE, this.trainStationDialogCloseHandler);
            UI.displayPopup(this.m_trainStationDialog);
            if (this.m_trainState != TRAIN_STATE_IDLE_AWAY){
                this.updateWorkers();
            };
        }
        public function showTrainScheduleCatalog():void{
            if (!this.isNeighborGated){
                if (!this.isWaitingForTrain){
                    UI.displayCatalog("train", null, true, "train", true, false, true);
                } else {
                    this.showTrainStationDialog();
                };
            };
        }
        public function purchaseWelcomeTrain():void{
            var _local1:TrainTrip = new TrainTrip();
            _local1.isWelcomeTrip = true;
            _local1.commodityType = Commodities.GOODS_COMMODITY;
            _local1.commodityAmount = Global.gameSettings.getInt("welcomeTrainQuestAmount", 100);
            this.scrollToTrainStation();
            this.setCurrentTrip(_local1, true);
        }
        public function proposeSchedulePurchase(_arg1:String):void{
            StatsManager.sample(100, "trains", "choose_train", _arg1);
            this.m_purchaseCandidateItem = Global.gameSettings.getItemByName(_arg1);
            this.showTrainStationDialog();
        }
        public function performSchedulePurchase():void{
            var _local1:TrainWorkers;
            var _local2:TrainTrip;
            if (((((this.m_purchaseCandidateItem) && (this.isBuyAllowed))) && (!((this.m_purchaseCandidateItem.name == ""))))){
                Global.trainWorkerManager.clearWorkers(getWorkerBucket());
                _local1 = (Global.trainWorkerManager.addAndGetWorkers(getWorkerBucket()) as TrainWorkers);
                _local1.itemName = this.m_purchaseCandidateItem.name;
                _local1.commodityType = Commodities.GOODS_COMMODITY;
                _local1.timeSent = (GlobalEngine.getTimer() / 1000);
                if (this.m_purchaseCandidateItem.goods > 0){
                    _local1.operation = TrainWorkers.OP_SELL;
                    Global.player.commodities.remove(Commodities.GOODS_COMMODITY, this.m_purchaseCandidateItem.goods);
                } else {
                    _local1.operation = TrainWorkers.OP_BUY;
                    Global.player.gold = (Global.player.gold - this.m_purchaseCandidateItem.cost);
                };
                GameTransactionManager.addTransaction(new TSendTrain(_local1), true);
                _local2 = new TrainTrip();
                _local2.loadFromWorker(_local1);
                this.setCurrentTrip(_local2);
                this.trainDepart();
            };
        }
        public function popRequestStationsFeed():void{
            var _local3:String;
            var _local1:String = (this.m_currentTrip.itemName) ? this.m_currentTrip.itemName : this.m_purchaseCandidateItem.name;
            var _local2:Boolean = Global.world.viralMgr.sendTrainFeed(_local1, Global.player.cityName, getWorkerBucket());
            if (!_local2){
                _local3 = ZLoc.t("Dialogs", "TrainUI_alreadyAsked_message");
                UI.displayMessage(_local3, GenericDialogView.TYPE_OK, null, "trainUIAlreadyAsked", false, null, "TrainUI_alreadyAsked");
            };
        }
        private function setCurrentTrip(_arg1:TrainTrip, _arg2:Boolean=false):void{
            if (_arg2){
                if (this.m_currentTrip){
                    switch (this.m_trainState){
                        case TRAIN_STATE_ARRIVING:
                        case TRAIN_STATE_IDLE_AT_STATION:
                            this.m_tripQueue.push(_arg1);
                            break;
                        default:
                            this.m_tripQueue.unshift(this.m_currentTrip);
                            this.m_currentTrip = _arg1;
                    };
                } else {
                    this.m_tripQueue.push(_arg1);
                };
            } else {
                this.m_tripQueue.push(_arg1);
            };
            this.pumpTrips();
        }
        private function pumpTrips():void{
            if ((((this.m_tripQueue.length > 0)) && (!(this.m_currentTrip)))){
                this.m_currentTrip = this.m_tripQueue.shift();
                dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATION_LIST_UPDATE));
            };
        }
        private function unsetCurrentTrip():void{
            this.m_currentTrip = null;
            this.m_trainStation.forceUpdateArrow();
            this.m_hasPerformedAnticipatedArrivalSync = false;
        }
        private function completeCurrentTrip():void{
            var _local1:TrainWorkers;
            if (this.m_currentTrip){
                if (this.m_currentTrip.isWelcomeTrip){
                    GameTransactionManager.addTransaction(new TTrainWelcomeOrder());
                } else {
                    _local1 = (Global.trainWorkerManager.getWorkers(getWorkerBucket()) as TrainWorkers);
                    if (_local1){
                        GameTransactionManager.addTransaction(new TAcceptTrain());
                        Global.trainWorkerManager.clearWorkers(getWorkerBucket());
                    };
                };
            };
        }
        private function spawnRewardDoobers():void{
            var _local1:Array;
            if (this.m_currentTrip){
                if (this.m_world.dooberManager.isDoobersEnabled()){
                    _local1 = this.generateDoobers(this.m_currentTrip.coins, 0, this.m_currentTrip.commodityAmount, this.m_currentTrip.commodityType);
                    this.m_world.dooberManager.createBatchDoobers(_local1, null, this.m_trainStation.getPosition().x, this.m_trainStation.getPosition().y);
                } else {
                    if (this.m_currentTrip.commodityAmount >= 0){
                        Global.player.commodities.add(this.m_currentTrip.commodityType, this.m_currentTrip.commodityAmount);
                    };
                    this.m_trainStation.doResourceChanges(0, this.m_currentTrip.coins, 0, this.m_currentTrip.commodityAmount, this.m_currentTrip.commodityType);
                };
            };
        }
        private function updateWorkers(_arg1:Boolean=false):void{
            var _local2:TWorkersSync;
            if (((_arg1) || (((this.m_lastWorkerSyncTime + WORKER_SYNC_INTERVAL) < (GlobalEngine.getTimer() / 1000))))){
                this.m_lastWorkerSyncTime = (GlobalEngine.getTimer() / 1000);
                _local2 = new TWorkersSync(WorkerManager.FEATURE_TRAINS, Global.trainWorkerManager);
                _local2.addEventListener(Event.COMPLETE, this.workerSyncHandler);
                GameTransactionManager.addTransaction(_local2, true);
            };
        }
        private function trainAwaitClearance():void{
            this.m_trainState = TRAIN_STATE_AWAITING_CLEARANCE;
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
            this.m_trainStation.forceUpdateArrow();
            if (this.m_currentTrip){
                if (this.m_currentTrip.isWelcomeTrip){
                    this.grantTrainClearance();
                } else {
                    this.updateWorkers(true);
                    TrainUI.showTrainAtStationHUDIcon(true, this);
                };
            };
        }
        private function trainArrive():void{
            this.m_trainSpeed = this.m_trainTerminalVelocity;
            this.m_trainState = TRAIN_STATE_ARRIVING;
            this.m_train.displayObject.alpha = 0;
            this.m_hasTrainBegunStop = false;
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
            this.m_trainStation.forceUpdateArrow();
            this.m_trainEndPos = this.getStationDockingPosition(this.m_train);
            var _local1:Vector3 = this.m_trainTracks.getSize();
            this.m_trainStartPos = this.m_trainEndPos.clone();
            var _local2 = -1;
            if (_local1.x > _local1.y){
                this.m_trainStartPos.x = this.m_maxTileX;
                _local2 = Constants.DIRECTION_SW;
            } else {
                this.m_trainStartPos.y = this.m_maxTileY;
                _local2 = Constants.DIRECTION_SE;
            };
            var _local3:Number = (this.m_trainSpeed * TRAIN_ARRIVAL_TIME);
            var _local4:Vector3 = this.m_trainStartPos.subtract(this.m_trainEndPos);
            if (_local4.length() > _local3){
                _local4 = _local4.normalize();
                _local4 = _local4.scale(_local3);
                this.m_trainStartPos = this.m_trainEndPos.add(_local4);
            };
            this.m_train.setPosition(this.m_trainStartPos.x, this.m_trainStartPos.y);
            if ((((_local2 >= 0)) && (!((_local2 == this.m_train.getDirection()))))){
                this.m_train.setDirection(_local2);
                this.m_train.reloadImage();
            };
            this.m_trainDecelerationDistanceFromStation = (Math.pow(this.m_trainTerminalVelocity, 2) / (2 * TRAIN_VELOCITY_DELTA));
            TweenLite.to(this.m_train.displayObject, TRAIN_FADE_TIME, {alpha:1});
            this.m_train.setSmokeEnabled(true);
            Sounds.play(TRAIN_SOUND_MOVING);
            if (this.m_currentTrip){
                this.completeCurrentTrip();
            };
        }
        private function trainIdleAtStation():void{
            this.m_trainSpeed = 0;
            this.m_trainState = TRAIN_STATE_IDLE_AT_STATION;
            this.m_train.displayObject.alpha = 1;
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
            this.m_trainStation.forceUpdateArrow();
            this.m_trainStartPos = this.getStationDockingPosition(this.m_train);
            this.m_train.setPosition(this.m_trainStartPos.x, this.m_trainStartPos.y);
            this.m_train.setSmokeEnabled(false);
        }
        private function trainDepart():void{
            this.m_trainSpeed = 0;
            this.m_trainState = TRAIN_STATE_DEPARTING;
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
            this.m_trainStation.forceUpdateArrow();
            this.m_trainStartPos = this.getStationDockingPosition(this.m_train);
            var _local1:Vector3 = this.m_trainTracks.getSize();
            this.m_trainEndPos = this.m_trainStartPos.clone();
            var _local2 = -1;
            if (_local1.x > _local1.y){
                this.m_trainEndPos.x = this.m_minTileX;
                _local2 = Constants.DIRECTION_SW;
            } else {
                this.m_trainEndPos.y = this.m_minTileY;
                _local2 = Constants.DIRECTION_SE;
            };
            this.m_train.setPosition(this.m_trainStartPos.x, this.m_trainStartPos.y);
            if ((((_local2 >= 0)) && (!((_local2 == this.m_train.getDirection()))))){
                this.m_train.setDirection(_local2);
                this.m_train.reloadImage();
            };
            TweenLite.to(this.m_train.displayObject, TRAIN_FADE_TIME, {alpha:1});
            this.m_train.setSmokeEnabled(true);
            Sounds.play(TRAIN_SOUND_LEAVES);
            Sounds.play(TRAIN_SOUND_MOVING);
        }
        private function trainIdleAway():void{
            this.m_trainSpeed = 0;
            this.m_trainState = TRAIN_STATE_IDLE_AWAY;
            this.m_train.setSmokeEnabled(false);
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
            this.m_trainStation.forceUpdateArrow();
            TweenLite.to(this.m_train.displayObject, TRAIN_FADE_TIME, {alpha:0});
        }
        private function trainEnRoute():void{
            this.trainIdleAway();
            this.m_trainState = TRAIN_STATE_EN_ROUTE;
            this.m_trainStation.forceUpdateArrow();
            dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TRAIN_STATE_UPDATE));
        }
        private function enterTrainStateIdleAway(_arg1:Number):void{
            if (this.m_currentTrip){
                this.trainEnRoute();
            } else {
                this.pumpTrips();
            };
        }
        private function enterTrainStateEnRoute(_arg1:Number):void{
            if (((this.m_currentTrip) && (((this.m_currentTrip.isWelcomeTrip) || ((this.m_currentTrip.timeLeft <= 0)))))){
                this.trainAwaitClearance();
            };
        }
        private function enterTrainStateAwaitingClearance(_arg1:Number):void{
            if (((this.m_trainHasClearance) || (this.m_currentTrip.isWelcomeTrip))){
                this.m_trainHasClearance = false;
                this.trainArrive();
            };
        }
        private function enterTrainStateArriving(_arg1:Number):void{
            var _local2:Vector3 = this.m_trainEndPos.subtract(this.m_train.getPosition());
            if (_local2.length() < this.m_trainDecelerationDistanceFromStation){
                if (!this.m_hasTrainBegunStop){
                    Sounds.play(TRAIN_SOUND_ARRIVES);
                    Sounds.stop(TRAIN_SOUND_MOVING);
                    this.m_hasTrainBegunStop = true;
                };
                this.m_trainSpeed = Math.max(0, (this.m_trainSpeed - (TRAIN_VELOCITY_DELTA * _arg1)));
            };
            var _local3:Vector3 = this.m_trainEndPos.subtract(this.m_trainStartPos).normalize().scale((this.m_trainSpeed * _arg1));
            var _local4:Vector3 = this.m_train.getPosition().add(_local3);
            this.m_train.setPosition(_local4.x, _local4.y, _local4.z);
            this.m_train.conditionallyReattach();
            this.m_train.adjustSmokeForTrainSpeed(this.m_trainSpeed);
            if (this.m_trainSpeed <= 0){
                this.trainIdleAtStation();
            };
        }
        private function enterTrainStateIdleAtStation(_arg1:Number):void{
            if (this.m_currentTrip){
                this.spawnRewardDoobers();
                this.unsetCurrentTrip();
                this.pumpTrips();
                if (this.m_currentTrip){
                    this.trainEnRoute();
                } else {
                    this.trainDepart();
                };
            };
        }
        private function enterTrainStateDeparting(_arg1:Number):void{
            this.m_trainSpeed = Math.min(this.m_trainTerminalVelocity, (this.m_trainSpeed + (TRAIN_VELOCITY_DELTA * _arg1)));
            var _local2:Vector3 = this.m_trainEndPos.subtract(this.m_trainStartPos).normalize().scale((this.m_trainSpeed * _arg1));
            var _local3:Vector3 = this.m_train.getPosition().add(_local2);
            this.m_train.setPosition(_local3.x, _local3.y, _local3.z);
            this.m_train.conditionallyReattach();
            this.m_train.adjustSmokeForTrainSpeed(this.m_trainSpeed);
            if (((this.m_currentTrip) && (((this.m_currentTrip.isWelcomeTrip) || ((this.m_currentTrip.timeLeft <= 0)))))){
                this.trainEnRoute();
                return;
            };
            if ((((_local3.x < this.m_trainEndPos.x)) || ((_local3.y < this.m_trainEndPos.y)))){
                if (this.m_currentTrip){
                    this.trainEnRoute();
                } else {
                    this.trainIdleAway();
                };
            };
        }
        protected function generateDoobers(_arg1:int, _arg2:int, _arg3:int, _arg4:String):Array{
            var _local6:int;
            var _local7:int;
            var _local11:int;
            var _local5:Array = new Array();
            var _local8:int = Global.gameSettings.getInt("trainAmountPerDoober", 3);
            var _local9:int = Global.gameSettings.getInt("trainMaxDoobers", 6);
            var _local10:int;
            if (_arg1 > 0){
                _local6 = Math.floor(Math.min((_arg1 / _local8), _local9));
                _local7 = Math.floor((_arg1 / _local6));
                _local11 = (_arg1 % _local6);
                _local10 = 0;
                while (_local10 < _local6) {
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(Doober.DOOBER_COIN, _local7), _local7));
                    _local10++;
                };
                if (_local11 > 0){
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(Doober.DOOBER_COIN, _local11), _local11));
                };
            };
            if (_arg2 > 0){
                _local6 = Math.floor(Math.min((_arg2 / _local8), _local9));
                _local7 = Math.floor((_arg2 / _local6));
                _local11 = (_arg2 % _local6);
                _local10 = 0;
                while (_local10 < _local6) {
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(Doober.DOOBER_XP, _local7), _local7));
                    _local10++;
                };
                if (_local11 > 0){
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(Doober.DOOBER_XP, _local11), _local11));
                };
            };
            if (_arg3 > 0){
                _local6 = Math.floor(Math.min((_arg3 / _local8), _local9));
                _local7 = Math.floor((_arg3 / _local6));
                _local11 = (_arg3 % _local6);
                _local10 = 0;
                while (_local10 < _local6) {
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(_arg4, _local7), _local7));
                    _local10++;
                };
                if (_local11 > 0){
                    _local5.push(new Array(Global.gameSettings.getDooberFromType(_arg4, _local11), _local11));
                };
            };
            return (_local5);
        }
        public function getStationDockingPosition(_arg1:NPC):Vector3{
            var _local2:Vector3 = this.m_trainTracks.getPosition();
            var _local3:Vector3 = this.m_trainStation.getPosition();
            _local3.x++;
            _local3.y++;
            var _local4:Number = _arg1.roadOffset;
            var _local5:Vector3 = this.m_trainTracks.getSize();
            if (_local5.x > _local5.y){
                _local2.y = (_local2.y + (_local5.y * 0.5));
                _local2.y = (_local2.y + (_local4 * _local5.y));
                _local2.x = _local3.x;
            } else {
                _local2.x = (_local2.x + (_local5.x * 0.5));
                _local2.x = (_local2.x + (_local4 * _local5.x));
                _local2.y = _local3.y;
            };
            return (_local2);
        }
        private function updateTrain(_arg1:Number):void{
            switch (this.m_trainState){
                case TRAIN_STATE_IDLE_AWAY:
                    this.enterTrainStateIdleAway(_arg1);
                    break;
                case TRAIN_STATE_EN_ROUTE:
                    this.enterTrainStateEnRoute(_arg1);
                    break;
                case TRAIN_STATE_AWAITING_CLEARANCE:
                    this.enterTrainStateAwaitingClearance(_arg1);
                    break;
                case TRAIN_STATE_ARRIVING:
                    this.enterTrainStateArriving(_arg1);
                    break;
                case TRAIN_STATE_IDLE_AT_STATION:
                    this.enterTrainStateIdleAtStation(_arg1);
                    break;
                case TRAIN_STATE_DEPARTING:
                    this.enterTrainStateDeparting(_arg1);
                    break;
            };
        }
        private function updateAndSync():void{
            var _local1:TrainStopCell;
            var _local2:TrainStopCell;
            var _local3:int;
            var _local4:int;
            var _local5:Point;
            if (((this.m_currentTrip) && (!(this.m_currentTrip.isWelcomeTrip)))){
                _local3 = this.m_currentTrip.timeLeft;
                if (_local3 != this.m_trainArrivalTime){
                    this.m_trainArrivalTime = _local3;
                    dispatchEvent(new TrainManagerEvent(TrainManagerEvent.TIME_UPDATE));
                };
                _local4 = ((this.m_currentTrip.transactionType == TrainWorkers.OP_BUY)) ? this.m_currentTrip.commodityAmount : this.m_currentTrip.coins;
                if (_local4 != this.m_trainRewardAmount){
                    this.m_trainRewardAmount = _local4;
                    dispatchEvent(new TrainManagerEvent(TrainManagerEvent.REWARD_UPDATE));
                };
                if (((!(this.m_hasPerformedAnticipatedArrivalSync)) && ((this.m_currentTrip.timeLeft < WORKER_SYNC_BEFORE_ARRIVAL)))){
                    this.m_hasPerformedAnticipatedArrivalSync = true;
                    this.updateWorkers(true);
                };
            };
            for each (_local2 in this.m_trainStopCells) {
                if (_local2.hitTestMouse()){
                    _local1 = _local2;
                    break;
                };
            };
            if (_local1 != this.m_lastTrainStopCellRolledOver){
                if (((this.m_trainStopCellTooltip) && (this.m_trainStopCellTooltip.parent))){
                    this.m_trainStopCellTooltip.parent.removeChild(this.m_trainStopCellTooltip);
                };
                this.m_lastTrainStopCellRolledOver = _local1;
                if (((((((this.m_trainStationDialog) && (!(this.m_trainStationDialog.hasOverlay)))) && (this.m_lastTrainStopCellRolledOver))) && (this.m_lastTrainStopCellRolledOver.friend))){
                    this.m_trainStopCellTooltip = new TrainStopTooltip();
                    this.m_trainStopCellTooltip.changeInfo(this.m_lastTrainStopCellRolledOver.friend.name);
                    _local5 = this.m_lastTrainStopCellRolledOver.parent.localToGlobal(new Point(this.m_lastTrainStopCellRolledOver.x, this.m_lastTrainStopCellRolledOver.y));
                    this.m_trainStopCellTooltip.x = ((_local5.x - (this.m_trainStopCellTooltip.width / 2)) + (this.m_lastTrainStopCellRolledOver.width / 2));
                    this.m_trainStopCellTooltip.y = (_local5.y - this.m_trainStopCellTooltip.height);
                    Global.stage.addChild(this.m_trainStopCellTooltip);
                };
            };
        }
        private function updateBounds():void{
            var _local3:Point;
            if (this.m_maxTileX > 0){
                return;
            };
            var _local1:Rectangle = Global.world.overlayBackgroundRect;
            if (((!(_local1)) || (!(this.m_trainTracks)))){
                return;
            };
            var _local2:Vector3 = this.m_trainStation.getPosition();
            _local2.x = (_local2.x - 3);
            _local2.y = (_local2.y - 3);
            var _local4 = 1;
            while (_local4 < 150) {
                _local3 = IsoMath.tilePosToPixelPos((_local2.x + _local4), _local2.y, 0, true);
                if ((((_local3.x < _local1.right)) && ((_local3.y > _local1.top)))){
                    this.m_maxTileX = (_local2.x + _local4);
                };
                _local3 = IsoMath.tilePosToPixelPos(_local2.x, (_local2.y + _local4), 0, true);
                if ((((_local3.x > _local1.left)) && ((_local3.y > _local1.top)))){
                    this.m_maxTileY = (_local2.y + _local4);
                };
                _local4++;
            };
            _local4 = 1;
            while (_local4 < 150) {
                _local3 = IsoMath.tilePosToPixelPos((_local2.x - _local4), _local2.y, 0, true);
                if ((((_local3.x > _local1.left)) && ((_local3.y < _local1.bottom)))){
                    this.m_minTileX = (_local2.x - _local4);
                };
                _local3 = IsoMath.tilePosToPixelPos(_local2.x, (_local2.y - _local4), 0, true);
                if ((((_local3.x > _local1.left)) && ((_local3.y < _local1.bottom)))){
                    this.m_minTileY = (_local2.y - _local4);
                };
                _local4++;
            };
        }
        public function generateCrossings():void{
            var _local1:TrainCrossing;
            var _local2:Vector3;
            var _local3:Vector3;
            var _local4:int;
            var _local5:int;
            var _local6:int;
            var _local7:Vector3;
            var _local8:Vector3;
            var _local9:int;
            var _local10:Array;
            var _local11:Boolean;
            var _local12:String;
            var _local13:int;
            var _local14:Boolean;
            var _local15:Road;
            var _local16:TrainCrossing;
            if (!this.m_trainTracks){
                this.onGameLoaded(null);
            };
            for each (_local1 in this.m_crossings) {
                _local1.detach();
            };
            this.m_crossings = [];
            if (this.m_trainTracks){
                _local2 = this.m_trainTracks.getPosition();
                _local3 = this.m_trainTracks.getSize();
                _local4 = _local3.y;
                _local5 = 0;
                _local6 = 1;
                if (_local3.x > _local3.y){
                    _local4 = _local3.x;
                    _local5 = 1;
                    _local6 = 0;
                };
                _local7 = new Vector3();
                _local8 = new Vector3();
                _local9 = 0;
                while (_local9 < _local4) {
                    _local2.x = (_local2.x + _local5);
                    _local2.y = (_local2.y + _local6);
                    _local7.x = (_local2.x + (_local6 * Road.SIZE_X));
                    _local7.y = (_local2.y + (_local5 * Road.SIZE_Y));
                    _local8.x = (_local2.x - (_local6 * Road.SIZE_X));
                    _local8.y = (_local2.y - (_local5 * Road.SIZE_Y));
                    _local10 = this.m_world.getCollisionMap().getObjectsByPosition(_local7.x, _local7.y);
                    _local11 = false;
                    _local12 = "";
                    _local13 = 0;
                    while (_local13 < _local10.length) {
                        _local15 = (_local10[_local13] as Road);
                        if (((_local15) && (_local15.getPosition().equals(_local7)))){
                            _local11 = true;
                            _local12 = _local15.baseRoadName();
                        };
                        _local13++;
                    };
                    _local10 = this.m_world.getCollisionMap().getObjectsByPosition(_local8.x, _local8.y);
                    _local14 = false;
                    _local13 = 0;
                    while (_local13 < _local10.length) {
                        _local15 = (_local10[_local13] as Road);
                        if (((_local15) && (_local15.getPosition().equals(_local8)))){
                            _local14 = true;
                        };
                        _local13++;
                    };
                    if (!_local14){
                        _local8.x = (_local8.x - _local6);
                        _local8.y = (_local8.y - _local5);
                        _local10 = this.m_world.getCollisionMap().getObjectsByPosition(_local8.x, _local8.y);
                        _local13 = 0;
                        while (_local13 < _local10.length) {
                            _local15 = (_local10[_local13] as Road);
                            if (((_local15) && (_local15.getPosition().equals(_local8)))){
                                if ((((_local6 > 0)) && ((_local15.getSize().x > Road.SIZE_X)))){
                                    _local14 = true;
                                };
                                if ((((_local5 > 0)) && ((_local15.getSize().y > Road.SIZE_Y)))){
                                    _local14 = true;
                                };
                            };
                            _local13++;
                        };
                    };
                    if (((_local11) && (_local14))){
                        _local16 = new TrainCrossing(_local12);
                        this.m_crossings.push(_local16);
                        _local16.setPosition(_local2.x, _local2.y);
                        _local16.setOuter(this.m_world);
                        _local16.attach();
                        _local16.m_orientation_X = !((_local6 == 0));
                    };
                    _local9++;
                };
            };
        }
        public function initialize():void{
        }
        public function cleanUp():void{
        }
        public function stopObserving():void{
            this.m_world.removeObserver(this);
        }
        public function update(_arg1:Number):void{
            this.updateBounds();
            this.updateTrain(_arg1);
            this.updateAndSync();
        }
        public function onGameLoaded(_arg1:Object):void{
            var _local3:GameObject;
            this.createTrain();
            this.syncWorkers();
            TrainUI.showTrainAtStationHUDIcon(false, this);
            var _local2:Array = this.m_world.getObjectsByTypes([WorldObjectTypes.TRAIN_STATION]);
            for each (_local3 in _local2) {
                if ((_local3 is TrainTracks)){
                    this.m_trainTracks = (_local3 as TrainTracks);
                } else {
                    if ((_local3 is TrainStation)){
                        this.m_trainStation = (_local3 as TrainStation);
                    };
                };
            };
        }
        public function onResourceChange(_arg1:MapResource, _arg2:Vector3, _arg3:Vector3):void{
        }
        private function trainStationDialogCloseHandler(_arg1:Event):void{
            if (this.m_trainStationDialog){
                this.m_trainStationDialog.removeEventListener(Event.CLOSE, this.trainStationDialogCloseHandler);
            };
            this.m_trainStationDialog = null;
            this.m_trainStopCells = new Vector.<TrainStopCell>();
        }
        private function workerSyncHandler(_arg1:Event):void{
            (_arg1.currentTarget as TWorkersSync).removeEventListener(Event.COMPLETE, this.workerSyncHandler);
            this.syncWorkers();
        }
        public function accepted(_arg1:TrainOrder, _arg2:int, _arg3:int):void{
        }
        public function declined(_arg1:TrainOrder, _arg2:int):void{
        }
        public function getLoadingUIPos():Point{
            return (new Point());
        }
        public function later(_arg1:TrainOrder, _arg2:int):void{
        }
        public function onMFSLoaded(_arg1:Boolean):void{
        }
        public function onNeighborAdded():void{
        }
        public function placeInitialTrainOrder(_arg1:String, _arg2:int, _arg3:String):void{
        }
        public function updateAmountAccepted(_arg1:TrainOrder, _arg2:int, _arg3:int):void{
        }

    }
}//package Classes.sim 
